#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>

int flag_width = 400;
int flag_height = 240;

void offset_up_flag(int row, int col, int (*lcd_mmap)[col])
{
    int offset = 0;

    while (offset + flag_height <= row)
    {
        for (int i = row - 1; i > flag_height; i--)
        {
            for (int j = 0; j < flag_width; j++)
            {
                if (i > flag_height / 3 * 2 + flag_height)
                {
                    lcd_mmap[i - offset][j] = 0x00FFFF00; // 黄色
                }
                else if (i > flag_height / 3 + flag_height)
                {
                    lcd_mmap[i - offset][j] = 0x00FF0000; // 红色
                }
                else
                {
                    lcd_mmap[i - offset][j] = 0x00000000; // 黑色
                }
            }
        }
        sleep(0.99);
        for (int j = 0; j < flag_width; j++)
        {
            lcd_mmap[row - offset - 1][j] = 0x000000ff;
        }
        sleep(0.2);
        offset++;
    }
}

void offset_down_flag(int row, int col, int (*lcd_mmap)[col])
{
    int offset = 0;

    while (offset + flag_height <= row)
    {
        for (int i = 0; i < flag_height; i++)
        {
            for (int j = flag_width; j < col; j++)
            {
                if (i > flag_height / 3 * 2)
                {
                    lcd_mmap[i + offset][j] = 0x00FFFF00; // 黄色
                }
                else if (i > flag_height / 3)
                {
                    lcd_mmap[i + offset][j] = 0x00FF0000; // 红色
                }
                else
                {
                    lcd_mmap[i + offset][j] = 0x00000000; // 黑色
                }
            }
        }
        sleep(0.99);
        for (int j = flag_width; j < col; j++)
        {
            lcd_mmap[offset][j] = 0x000000ff;
        }
        sleep(0.2);
        offset++;
    }
}

void offset_left_flag(int row, int col, int (*lcd_mmap)[col])
{
    int offset = 0;
    while (offset + flag_width <= col)
    {
        for (int i = 0; i < flag_height; i++)
        {
            for (int j = 0; j < flag_width; j++)
            {
                if (i > flag_height / 3 * 2)
                {
                    lcd_mmap[i][j + offset] = 0x00FFFF00; // 黄色
                }
                else if (i > flag_height / 3)
                {
                    lcd_mmap[i][j + offset] = 0x00FF0000; // 红色
                }
                else
                {
                    lcd_mmap[i][j + offset] = 0x00000000; // 黑色
                }
            }
        }
        sleep(0.99);
        for (int i = 0; i < flag_height; i++)
        {
            lcd_mmap[i][offset] = 0x000000ff;
        }
        sleep(0.2);
        offset++;
    }
}

void offset_right_flag(int row, int col, int (*lcd_mmap)[col])
{
    int offset = 0;
    while (offset + flag_width <= col)
    {
        for (int i = flag_height; i < row; i++)
        {
            for (int j = flag_width - 1; j > 0; j--)
            {
                if (i > flag_height / 3 * 2 + flag_height)
                {
                    lcd_mmap[i][col - j - offset] = 0x00FFFF00; // 黄色
                }
                else if (i > flag_height / 3 + flag_height)
                {
                    lcd_mmap[i][col - j - offset] = 0x00FF0000; // 红色
                }
                else
                {
                    lcd_mmap[i][col - j - offset] = 0x00000000; // 黑色
                }
            }
        }
        sleep(0.99);
        for (int i = flag_height - 1; i < row; i++)
        {
            lcd_mmap[i][col - offset - 1] = 0x000000ff;
        }
        sleep(0.2);
        offset++;
    }
}

void set_screen_blue(int (*lcd_mmap)[800])
{
    for (int i = 0; i < 480; i++)
    {
        for (int j = 0; j < 800; j++)
        {
            lcd_mmap[i][j] = 0x000000FF; // 蓝色
        }
    }
}

int main()
{
    int fd;
    fd = open("/dev/fb0", O_RDWR);
    if (fd < 0)
    {
        printf("open /dev/fb0 failed error: %s\n", strerror(errno));
        return -1;
    }

    printf("open /dev/fb0 success\n");

    int (*lcd_mmap)[800] = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    set_screen_blue(lcd_mmap);
    while (1)
    {
        offset_left_flag(480, 800, lcd_mmap);
        offset_down_flag(480, 800, lcd_mmap);
        offset_right_flag(480, 800, lcd_mmap);
        offset_up_flag(480, 800, lcd_mmap);
    }
    close(fd);
    return 0;
}